package com.second.app.thread.reentrant.condition;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author gyz
 * @date 2021/2/3 14:33
 */
public class Main {
    /**
     * 讲义版
     */
    private final static ReentrantLock reentrantLock = new ReentrantLock();

    private final static Condition conditionA = reentrantLock.newCondition();

    private final static Condition conditionB = reentrantLock.newCondition();

    private final static Condition conditionC = reentrantLock.newCondition();

    volatile static Integer nextPrintWho = 1;

    public static void main(String[] args) {
        Thread t0 = new Thread(new Runnable() {
            @Override
            public void run() {
                reentrantLock.lock();
                try {
                    if (nextPrintWho != 1) {
                        conditionA.await();
                    }
                    for (int i = 0; i < 3; i++) {
                        System.out.println("ThreadA " + (i + 1));
                    }
                    nextPrintWho = 2;
                    conditionB.signalAll();
                } catch (InterruptedException exception) {
                    exception.printStackTrace();
                } finally {
                    reentrantLock.unlock();
                }
            }
        });

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                reentrantLock.lock();
                try {
                    if (nextPrintWho != 2) {
                        conditionA.await();
                    }
                    for (int i = 0; i < 3; i++) {
                        System.out.println("ThreadB " + (i + 1));
                    }
                    nextPrintWho = 3;
                    conditionC.signalAll();
                } catch (InterruptedException exception) {
                    exception.printStackTrace();
                } finally {
                    reentrantLock.unlock();
                }
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                reentrantLock.lock();
                try {
                    if (nextPrintWho != 3) {
                        conditionA.await();
                    }
                    for (int i = 0; i < 3; i++) {
                        System.out.println("ThreadC " + (i + 1));
                    }
                    nextPrintWho = 1;
                    conditionC.signalAll();
                } catch (InterruptedException exception) {
                    exception.printStackTrace();
                } finally {
                    reentrantLock.unlock();
                }
            }
        });

        Thread[] aArray = new Thread[5];
        Thread[] bArray = new Thread[5];
        Thread[] cArray = new Thread[5];
        for (int i = 0; i < 5; i++) {
            aArray[i] = new Thread(t0);
            bArray[i] = new Thread(t1);
            cArray[i] = new Thread(t2);
            aArray[i].start();
            bArray[i].start();
            cArray[i].start();

        }


    }

}
